home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
gamesrc
/
mancala
/
ab.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-24
|
2KB
|
87 lines
/* ab.c
*
* Crude, simple alpha-beta search.
*
* No pruning, yet.
*
* Requires the following to be defined:
* ab_position_t: Type that defines a board position.
* ab_score_t: Score type for score of a move.
* AB_WIN_SCORE: Score that signifies a win.
* AB_MAX_MOVES: Max moves that will ever be available from a single
* position.
* ab_move_t: Type that definies a move.
* ab_storage_t: Data needed to store a move's effects and undo them.
* ab_score_t AB_MOVE_VAL(move): Value of a move.
* int AB_PLAYER_TO_MOVE(pos): 0 or 1.
* int ab_generate_moves(pos, moves);
* ab_score_t ab_do_move(position, move, storage): Make move to position.
* void ab_undo_move(position, storage): Undo a move.
* int ab_move_cmp(mv1, mv2): Return >0 if mv1 has a higher score,
* is better, <0 if mv2 is better. Should never return 0.
*/
#include "mancala.h"
#include <stdio.h>
static ab_score_t rsearch(ab_position_t *pos, int depth,
ab_move_t *bestmove);
ab_move_t ab_search(ab_position_t *pos, int depth) {
ab_move_t result;
ab_score_t score;
do {
score = rsearch(pos, depth, &result);
--depth;
} while ((score <= -AB_WIN_SCORE) && (depth > 0));
return(result);
}
static ab_score_t rsearch(ab_position_t *pos, int depth,
ab_move_t *bestmove) {
ab_move_t moves[AB_MAX_MOVES];
int n_moves, i, tomove = AB_PLAYER_TO_MOVE(*pos);
ab_storage_t mvmade;
ab_score_t bscore, cscore, mscore;
bscore = -AB_WIN_SCORE;
n_moves = ab_generate_moves(pos, moves);
if (n_moves == 0)
return(0);
qsort(moves, n_moves, sizeof(ab_move_t), ab_move_cmp);
if (bestmove != NULL)
*bestmove = moves[0];
if (AB_MOVE_VAL(moves[0]) >= AB_WIN_SCORE)
return(AB_WIN_SCORE);
else if (AB_MOVE_VAL(moves[0]) <= -AB_WIN_SCORE)
return(-AB_WIN_SCORE);
if (depth == 1)
return(AB_MOVE_VAL(moves[0]));
for (i = 0; i < n_moves; ++i) {
cscore = ab_do_move(pos, &moves[i], &mvmade);
mscore = rsearch(pos, depth - 1, NULL);
if (AB_PLAYER_TO_MOVE(*pos) != tomove)
mscore = -mscore;
ab_undo_move(pos, &mvmade);
if (mscore >= AB_WIN_SCORE) {
if (bestmove != NULL)
*bestmove = moves[i];
return(AB_WIN_SCORE);
}
if (mscore > -AB_WIN_SCORE) {
cscore += mscore;
if (cscore > bscore) {
bscore = cscore;
if (bestmove != NULL)
*bestmove = moves[i];
}
}
}
return(bscore);
}